home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / src / java / net / inetad~1.jav < prev    next >
Encoding:
Text File  |  1996-01-12  |  8.9 KB  |  290 lines

  1. /*
  2.  * @(#)InetAddress.java    1.22 96/01/10 Jonathan Payne
  3.  *
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package java.net;
  21.  
  22. import java.util.Hashtable;
  23.  
  24. /**
  25.  * A class that represents Internet addresses.
  26.  *
  27.  * @version     1.22, 01/10/96
  28.  * @author     Jonathan Payne
  29.  * @author     Arthur van Hoff
  30.  * @author     Chris Warth
  31.  */
  32. public final 
  33. class InetAddress {
  34.     private static boolean inCheck = false;
  35.  
  36.     String hostName;
  37.     int address;    // Currently we only deal effectively with 32-bit addresses. 
  38.             // However this field can be expanded to be a byte array 
  39.             // or a 64-bit quantity without too much effort.
  40.     int family;
  41.  
  42.     /*
  43.      * Load net library into runtime.
  44.      */
  45.     static {
  46.     System.loadLibrary("net");
  47.     }
  48.  
  49.     /** 
  50.      * Constructor for the Socket.accept() method.
  51.      * This creates an empty InetAddress, which is filled in by
  52.      * the accept() method.  This InetAddress, however, is not
  53.      * put in the address cache, since it is not created by name.
  54.      */
  55.     InetAddress() {}
  56.  
  57.     /**
  58.      * Creates an InetAddress with the specified host name and IP address.
  59.      * @param hostName the specified host name
  60.      * @param addr the specified IP address.  The address is expected in 
  61.      *          network byte order.
  62.      * @exception UnknownHostException If the address is unknown.
  63.      */
  64.     InetAddress(String hostName, byte addr[]) {
  65.     this.hostName = new String(hostName);
  66.     this.family = getInetFamily();
  67.     /*
  68.      * We must be careful here to maintain the network byte
  69.      * order of the address.  As it comes in, the most
  70.      * significant byte of the address is in addr[0].  It
  71.      * actually doesn't matter what order they end up in the
  72.      * array, as long as it is documented and consistent.
  73.      */
  74.     address  = addr[3] & 0xFF;
  75.     address |= ((addr[2] << 8) & 0xFF00);
  76.     address |= ((addr[1] << 16) & 0xFF0000);
  77.     address |= ((addr[0] << 24) & 0xFF000000);
  78.     }
  79.  
  80.     /**
  81.      * Gets the hostname for this address; also the key in the 
  82.      * hashtable.
  83.      * If the host is equal to null, then this address refers to any
  84.      * of the local machine's available network addresses.
  85.      */
  86.     public String getHostName() {
  87.     if (hostName == null) {
  88.         try {
  89.         hostName = getHostByAddr(address);
  90.         } catch (UnknownHostException e) {
  91.         hostName = 
  92.            ((address >>> 24) & 0xFF) + "." +
  93.            ((address >>> 16) & 0xFF) + "." +
  94.            ((address >>>  8) & 0xFF) + "." +
  95.            ((address >>>  0) & 0xFF);
  96.         }
  97.     }
  98.  
  99.     return hostName;
  100.     }
  101.  
  102.     /**
  103.      * Returns the raw IP address in network byte order.  The highest
  104.      * order byte position is in addr[0]. To be prepared for 64-bit
  105.      * IP addresses n array of bytes is returned.
  106.  
  107.      * @return raw IP address in network byte order.
  108.      */
  109.     public byte[] getAddress() {    
  110.     byte[] addr = new byte[4];
  111.  
  112.     addr[0] = (byte) ((address >>> 24) & 0xFF);
  113.     addr[1] = (byte) ((address >>> 16) & 0xFF);
  114.     addr[2] = (byte) ((address >>> 8) & 0xFF);
  115.     addr[3] = (byte) (address & 0xFF);
  116.     return addr;
  117.     }
  118.  
  119.     /**
  120.      * Returns a hashcode for this InetAddress.
  121.      */
  122.     public int hashCode() {
  123.     return address;
  124.     }
  125.  
  126.     /**
  127.      * Compares this object against the specified object.
  128.      * @param obj the object to compare against.
  129.      * @return true if the objects are the same; false otherwise.
  130.      */
  131.     public boolean equals(Object obj) {
  132.     return (obj != null) && (obj instanceof InetAddress) &&
  133.         (((InetAddress)obj).address == address);
  134.     }
  135.  
  136.     /**
  137.      * Converts the InetAddress to a String.
  138.      */
  139.     public String toString() {
  140.     return ((hostName != null) ? hostName + "/" : "") +
  141.            ((address >>> 24) & 0xFF) + "." +
  142.            ((address >>> 16) & 0xFF) + "." +
  143.            ((address >>>  8) & 0xFF) + "." +
  144.            ((address >>>  0) & 0xFF);
  145.     }
  146.  
  147.     /* Cached addresses - our own litle nis, not! */
  148.     static Hashtable        addressCache = new Hashtable();
  149.     static InetAddress        unknownAddress;
  150.     static InetAddress        anyLocalAddress;
  151.     static InetAddress      localHost;
  152.  
  153.     static {
  154.     unknownAddress = new InetAddress();
  155.     anyLocalAddress = new InetAddress();
  156.     makeAnyLocalAddress(anyLocalAddress);
  157.     try {
  158.         localHost = getByName(getLocalHostName());
  159.     } catch (Exception ex) {
  160.         localHost = unknownAddress;
  161.     }
  162.     }
  163.  
  164.     /**
  165.      * Returns a network address for the indicated host.  A host name
  166.      * of null refers to default address for the local machine.  A local
  167.      * cache is used to speed access to addresses.  If all
  168.      * addresses for a host are needed, use the getAllByName() method.
  169.      * @param host the specified host
  170.      * @exception UnknownHostException If the address is unknown.
  171.      */
  172.     public static synchronized InetAddress getByName(String host)
  173.     throws UnknownHostException
  174.     {
  175.     if (host == null || host.length() == 0) {
  176.         return localHost;
  177.     }
  178.  
  179.     /* make sure the connection to the host is allowed, before we
  180.        create the InetAddress */
  181.     SecurityManager security = System.getSecurityManager();
  182.     if (security != null && !security.getInCheck()) {
  183.         security.checkConnect(host, -1);
  184.     }
  185.  
  186.     /* Cache.get can return: null, unknownAddress, InetAddress,
  187.     or InetAddress[] */
  188.     Object obj = addressCache.get(host);
  189.     if (obj == null) {
  190.         try {
  191.         /*
  192.          * Do not put the call to lookup() inside the
  193.          * constructor.  if you do you will still be
  194.          * allocating space when the lookup fails.
  195.          */
  196.         byte addr[] = lookupHostAddr(host);
  197.         obj = new InetAddress(host, addr);
  198.         } catch (UnknownHostException e) {
  199.         obj  = unknownAddress;
  200.         }
  201.         addressCache.put(host, obj);
  202.     } else if (obj instanceof InetAddress[]) {
  203.         InetAddress addr_array[] = (InetAddress []) obj;
  204.         obj = addr_array[0];
  205.     }
  206.         
  207.     if (obj == unknownAddress) {
  208.         /*
  209.          * We currently cache the fact that a host is unknown.
  210.          */
  211.         throw new UnknownHostException(host);
  212.     }
  213.     return (InetAddress) obj;
  214.     }
  215.  
  216.     /** 
  217.      * Given a hostname, returns an array of all the corresponding InetAddresses.  
  218.      * @exception UnknownHostException If the host name could not be resolved
  219.      */
  220.     public static synchronized InetAddress getAllByName(String host)[]
  221.     throws UnknownHostException
  222.     {
  223.     if (host == null) {
  224.         throw new UnknownHostException(host);
  225.     }
  226.  
  227.     /* make sure the connection to the host is allowed, before we
  228.        create the InetAddress */
  229.     SecurityManager security = System.getSecurityManager();
  230.     if (security != null && !security.getInCheck()) {
  231.         security.checkConnect(host, -1);
  232.     }
  233.  
  234.        /* Cache.get can return: null, unknownAddress, InetAddress,
  235.     or InetAddress[] */
  236.     Object obj = addressCache.get(host);
  237.     
  238.     /* If no entry in cache, or entry in the cache points to a single
  239.        InetAddress (not an array), then do the host lookup */
  240.     if (obj == null ||
  241.         ((obj!=unknownAddress) && (obj instanceof InetAddress)) ) {
  242.         try {
  243.         /*
  244.          * Do not put the call to lookup() inside the
  245.          * constructor.  if you do you will still be
  246.          * allocating space when the lookup fails.
  247.          */
  248.         byte[][] byte_array = lookupAllHostAddr(host);
  249.         InetAddress[] addr_array = new InetAddress[byte_array.length];
  250.         for (int i = 0; i < byte_array.length; i++) {
  251.             byte addr[] = byte_array[i];
  252.             addr_array[i] = new InetAddress(host, addr);
  253.         }
  254.         obj = addr_array;
  255.         } catch (UnknownHostException e) {
  256.         obj  = unknownAddress;
  257.         }
  258.         addressCache.put(host, obj);
  259.     } 
  260.         
  261.     if (obj == unknownAddress) {
  262.         /*
  263.          * We currently cache the fact that a host is unknown.
  264.          */
  265.         throw new UnknownHostException(host);
  266.     }
  267.     return (InetAddress []) obj;
  268.     }
  269.  
  270.     /**
  271.      * Returns the local host.
  272.      * @exception UnknownHostException If the host name could not be resolved
  273.      */
  274.     public static InetAddress getLocalHost() throws UnknownHostException {
  275.         if (localHost.equals(unknownAddress)) {
  276.         throw new UnknownHostException();
  277.     }
  278.     return localHost;
  279.     }
  280.  
  281.     private static native String getLocalHostName() throws UnknownHostException;
  282.     private static native void makeAnyLocalAddress(InetAddress addr);
  283.     private static native byte[] lookupHostAddr(String hostname) throws UnknownHostException;
  284.     private static native byte[][]
  285.         lookupAllHostAddr(String hostname) throws UnknownHostException;
  286.     private static native String getHostByAddr(int addr) throws UnknownHostException;
  287.     private static native int getInetFamily();
  288. }
  289.  
  290.